package org.log4jeditor.xml.editor;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.ui.texteditor.MarkerUtilities;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.junit.BeforeClass;
import org.log4jconfig.xml.editor.validation.ContentValidator;

/**
 * Made abstract, so won't be automatically picked up as test (since intended to
 * be subclassed).
 * 
 * Based on
 * http://dev.eclipse.org/viewcvs/index.cgi/incubator/sourceediting/tests
 * /org.eclipse
 * .wst.xsl.ui.tests/src/org/eclipse/wst/xsl/ui/tests/AbstractXSLUITest
 * .java?revision=1.2&root=WebTools_Project&view=markup
 * 
 */
// @RunWith(CustomBlockJUnit4ClassRunner.class)
@SuppressWarnings("restriction")
public class AbstractUITestCase {

	protected IJavaProject javaProject;

	protected IStructuredDocument document = null;
	protected ITextViewer sourceViewer = null;
	protected IPath log4jLibPath = new Path(System.getProperty("user.home")
			+ File.separator
			+ ".m2/repository/log4j/log4j/1.2.14/log4j-1.2.14.jar");;
	protected IFile file = null;

	private static final Logger LOGGER = LogManager
			.getLogger(AbstractUITestCase.class);

	@BeforeClass
	public static void setupWorkspace() throws Exception {
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		if (workspace.isAutoBuilding()) {
			IWorkspaceDescription description = workspace.getDescription();
			description.setAutoBuilding(false);
			workspace.setDescription(description);
		}

	}

	/**
	 * Called by subclasses to setup the workspace with project and files (xml,
	 * java, etc.)
	 * 
	 * @param fileName
	 * @throws Exception
	 */
	public void setupEditorConfiguration(String fileName) throws Exception {
		LOGGER.debug("Setting up project and document " + fileName);
		Long start = new Date().getTime();
		NullProgressMonitor monitor = new NullProgressMonitor();
		
		javaProject = WorkbenchTasks.createJavaProject("TestProject",
				Log4jConfigXMLEditorTestsPlugin
						.getTestFile("/projectfiles"), monitor);
		WorkbenchTasks.addJavaProjectLibrary(javaProject, log4jLibPath,
				monitor);
		file = WorkbenchTasks.getFile(javaProject.getProject().getName()
				+ File.separator + "src" + File.separator + fileName);
		document = WorkbenchTasks
				.openFileForEdit(file);
		sourceViewer = WorkbenchTasks.initializeSourceViewer(document);
		WorkbenchTasks.buildWorkspace(monitor);
		LOGGER.debug("Setting up project and document done in " + (new Date().getTime() - start) + " millis");
		
	}

	protected void tearDownProject() throws Exception {
		if (document != null) {
			IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(
					document);
			model.releaseFromEdit();
			
		}
		/*
		if (javaProject.exists()) {
			javaProject.getProject().delete(true, true, new NullProgressMonitor());
			javaProject.getProject().refreshLocal(IResource.DEPTH_INFINITE,
					new NullProgressMonitor());
		}*/

	}

	/**
	 * @return
	 * @throws BadLocationException
	 */
	protected int getDocumentOffset(int lineNumber, int columnNumber,
			String expectedNodeName) throws BadLocationException {
		int offset = sourceViewer.getDocument().getLineOffset(lineNumber - 1)
				+ columnNumber - 1;
		IDOMNode node = (IDOMNode) ContentAssistUtils.getNodeAt(sourceViewer,
				offset);
		assertEquals("Wrong node name returned:", expectedNodeName, node
				.getNodeName());
		return offset;
	}

	/**
	 * @return
	 * @throws CoreException
	 */
	protected IMarker[] getMarkers() throws CoreException {
		List<IMarker> defaultMarkers = Arrays.asList(file.findMarkers(
				ContentValidator.DEFAULT_MARKER_ID, true,
				IResource.DEPTH_INFINITE));
		List<IMarker> deprecatedMarkers = Arrays.asList(file.findMarkers(
				ContentValidator.DEPRECATED_ELEMENT_MARKER_ID, true,
				IResource.DEPTH_INFINITE));
		List<IMarker> markers = new ArrayList<IMarker>();
		markers.addAll(defaultMarkers);
		markers.addAll(deprecatedMarkers);
		for (IMarker marker : markers) {
			LOGGER.info("Found marker with message '"
					+ MarkerUtilities.getMessage(marker) + "' on line "
					+ MarkerUtilities.getLineNumber(marker));
		}
		return markers.toArray(new IMarker[defaultMarkers.size()
				+ deprecatedMarkers.size()]);
	}

	/**
	 * @param region
	 * @return
	 */
	protected Region getDirtyRegion(int offset) {
		IStructuredDocumentRegion region = ContentAssistUtils
				.getStructuredDocumentRegion(sourceViewer, offset);
		return new Region(region.getStartOffset(), region.getLength());
	}

}
